
cvtColor(src_gray, dst, CV_GRAY2BGR);//灰度转RGB（OpenCV2）
cvtColor(src_gray, dst, COLOR_GRAY2BGR);//灰度转RGB
cvtColor(src_gray, dst, COLOR_BGR2GRAY);//RGB转灰度


	//是边缘保留的滤波方法，避免边缘像素信息丢失，保留了图像轮廓不变。可以用于美颜中
	//高斯双边滤波	原始  新的  半径的范围  表示像素的差值100以内  不知道
bilateralFilter(zeor_a, new_img,5, 100, 10);
	
	//	//此句代码的OpenCV3版为：（转灰度图）
cvtColor(a_img, rgrb_a, COLOR_BGR2GRAY);

	//高斯滤波 权重是一个高斯分布  素值仍然较大  保留原有的特点  部分地克服了边缘信息的丢  无法完全避免，因为没有考虑像素值的不同
	//	原始  新的  X方向的高斯核标准偏差  Y方向的高斯核标准差
GaussianBlur(src, dst2, Size(5, 5), 11);

	//中值滤波 椒盐噪点 是一种统计排序滤波器，
medianBlur(src, dst, 5); //5为卷积核的大小

	//【3】先用使用 3x3内核来降噪（均值滤波）权重都为1  各个区域的像素值比较均匀，无法克服边缘像素信息丢失
blur(a_img, rgrb_a, Size(3, 3));

//轮廓提取
Canny(sre_zao, src_gray, 110, 200);//canny边缘检测算子
	//Canny()函数：，输入图像、，输出图像、第三个参数是低阈值、第四个参数是高阈值，第五个参数表示Sobel算子的孔径大小，默认值为3，高低阈值的比值最好在2:1到3:1之间。

	
	//图片的旋转
	cv::Size src_sz = src.size();
	cv::Size dst_sz(src_sz.width, src_sz.height);
	Point center = cv::Point(src.cols / 2, src.rows / 2);//旋转中心
	//这是一个防射变换矩阵
	Mat rot_mat =getRotationMatrix2D(center , 30.0, 1.0);//旋转位置  旋转角度  图像缩放因子
	cv::warpAffine(src, over, rot_mat, dst_sz);//输入图片  输出图片  放射变化矩阵  输出图片的尺寸


//https://blog.csdn.net/duwangthefirst/article/details/79971212
Canny(edge, edge, 3, 9, 3);


////【1】创建与src同类型和大小的矩阵(dst)
dstImage.create(srcImage.size(), srcImage.type());


	Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));//内核的形状（三种形式）  内核的尺寸（轮廓的粗细）  锚点的位置
	/*矩形：MORPH_RECT;
	交叉形：MORPH_CROSS;
	椭圆形：MORPH_ELLIPSE;*/
	Mat dst;
	erode(src, dst, element);//原始图片  腐蚀后的图   进行腐蚀操作的Mat 

//进行二值化
threshold(sre_zao, er_src, 105, 210, CV_THRESH_BINARY);
//adaptiveThreshold(sre_zao, er_src, 230, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 110, 0);
	//er_src = 110 < 100 ? (src < 150) : (src > 150);


//vector<Vec2f> lines;
HoughLines(src_gray, lines, 1, CV_PI / 180, 300, 0, 0);



//第二种方法（概率霍夫变换）
vector<Vec4f> plines;
HoughLinesP(src_gray, plines, 1, CV_PI / 180.0, 300, 0, 10);



//基于源图像的方法1  log对数增强
Mat logTransform1001(Mat srcImage, int c)
{
	//判断是否是图片
	if (srcImage.empty())
		cout << "No data" << endl;
	Mat resultImage = Mat::zeros(srcImage.size(), srcImage.type());
	add(srcImage, Scalar(1.0), srcImage); //计算 r+1
	srcImage.convertTo(srcImage, CV_32F); // 转化为32位浮点型
	log(srcImage, resultImage);           //计算log(1+r)
	resultImage = c * resultImage;
	//归一化处理
	normalize(resultImage, resultImage, 0, 255, NORM_MINMAX);
	convertScaleAbs(resultImage, resultImage);
	return resultImage;



//基于源图像的方法1  log对数增强（多通道）
Mat logTransform1002(Mat image, int c)
{
	Mat imageLog(image.size(), CV_32FC3);
	for (int i = 0; i < image.rows; i++)
	{
		for (int j = 0; j < image.cols; j++)
		{
			imageLog.at<Vec3f>(i, j)[0] =c * log(1 + image.at<Vec3b>(i, j)[0]);
			imageLog.at<Vec3f>(i, j)[1] =c * log(1 + image.at<Vec3b>(i, j)[1]);
			imageLog.at<Vec3f>(i, j)[2] =c * log(1 + image.at<Vec3b>(i, j)[2]);
		}
	}
	//归一化到0~255    
	normalize(imageLog, imageLog, 0, 255, CV_MINMAX);
	//转换成8bit图像显示    
	convertScaleAbs(imageLog, imageLog);
	return imageLog;
}



//幂函数增强
	Mat dst(src.size(), CV_32FC3);
	for (int i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			for (int m = 0; m < 3; m++)
			{
				dst.at<Vec3f>(i, j)[m] = (src.at<Vec3b>(i, j)[m])^(1);
			}
			//dst.at<uchar>(i, j) = (src.at<uchar>(i, j) ^ (1 / 10);
		}
	}


	//////归一化到0~255    
	//normalize(dst,dst, 0, 255, CV_MINMAX);
	normalize(dst, dst, 0, 255,CV_MINMAX);
	//////转换成8bit图像显示    
	convertScaleAbs(dst, dst);

}









int c = 2;
	Mat dst(src.size(), CV_32FC3);
	//Mat dst(src);
	for (int i = 0; i < src.rows; i++)
	{
		for (int k = 0; k < src.cols; k++)
		{
			for (int j = 0; j < 3; j++)
			{
				dst.at<Vec3f>(i, k)[j] =c * log(1 + src.at<Vec3b>(i,k)[j] );//防止以零为低数
			}
		}
	}

	////归一化到0~255    
	normalize(dst,dst, 0, 255, CV_MINMAX);
	////转换成8bit图像显示    
	convertScaleAbs(dst, dst);



//【1】读入视频
	VideoCapture capture("1.avi");

	//【2】循环显示每一帧
	while(1)  
	{  
		Mat frame;//定义一个Mat变量，用于存储每一帧的图像
		capture>>frame;  //读取当前帧
		imshow("读取视频",frame);  //显示当前帧
		waitKey(30);  //延时30ms
	}  
	return 0;     




namedWindow(window_name, CV_WINDOW_AUTOSIZE);
	//这个名字与imshow()里面的名字是一个的，
	createTrackbar("element size", window_name, &element_size, max_size, callback_demo);  //利用回调函数创建滑动按钮示例
	//滑动框的名字  滑动框在那个父的窗口实现   开始  结束  会掉
	callback_demo(0, 0);//在这里回调函数，参数好像固定
void callback_demo_erode(int, void*) {}





//概率霍夫变换
void houghp() {
    cv::Mat image = cv::imread("road.png");
    cv::Mat midImage;
    cv::Canny(image, midImage, 50, 200, 3);
    std::vector<cv::Vec4i> lines;
    cv::HoughLinesP(midImage, lines, 1, CV_PI / 180, 50);  // 输入的时二值图像，输出vector向量
    for (int i=0; i < lines.size(); i++) {
        cv::Point pt1(lines[i][0], lines[i][1]);
        cv::Point pt2(lines[i][2], lines[i][3]);
        cv::line(image, pt1, pt2, cv::Scalar(0, 255, 255));
    }
    cv::imshow("概率霍夫变换", image);
}






//分通道显示
vector<Mat> bgr_planes;
split(src, bgr_planes);

//imshow("b", bgr_planes[0]);
//imshow("g", bgr_planes[0]);
//imshow("r", bgr_planes[0]);

//设定像素取值范围
int histSize = 256;
float range[] = { 0,256 };
const float *histRanges = { range };

//三个通道分别计算直方图
Mat b_hist, g_hist, r_hist;
calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRanges, true, false);
calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRanges, true, false);
calcHist(&bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRanges, true, false);

	/*onst Mat* images：输入图像

	int nimages：输入图像的个数

	const int* channels：需要统计直方图的第几通道

	InputArray mask：掩膜，，计算掩膜内的直方图  ...Mat()

	OutputArray hist:输出的直方图数组

	int dims：需要统计直方图通道的个数

	const int* histSize：指的是直方图分成多少个区间，就是 bin的个数

	const float** ranges： 统计像素值得区间

	bool uniform = true::是否对得到的直方图数组进行归一化处理

	bool accumulate = false：在多个图像时，是否累计计算像素值得个数*/
	




	//创建直方图画布并归一化处理
int hist_h = src.rows;
int hist_w = src.cols;
int bin_w = hist_w / histSize;
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());



//render histogram chart  在直方图画布上画出直方图
for (int i = 1; i < histSize; i++)
{
	line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(b_hist.at<float>(i - 1))),
		Point((i)*bin_w, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, LINE_AA);
	line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(g_hist.at<float>(i - 1))),
		Point((i)*bin_w, hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, LINE_AA);
	line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(r_hist.at<float>(i - 1))),
		Point((i)*bin_w, hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, LINE_AA);
}


	imshow("直方图", histImage);





